//
//  AppDelegate.m
//  ibeacon
//
//  Created by apple on 2016/12/16.
//  Copyright © 2016年 hzq. All rights reserved.
//

#import "AppDelegate.h"
#import <CoreLocation/CoreLocation.h>
#import <CoreLocation/CLError.h>

// 可参考网站: http://www.cocoachina.com/articles/22253

@interface AppDelegate ()<CLLocationManagerDelegate>
@property (strong, nonatomic) CLBeaconRegion *myBeaconRegion;
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (nonatomic,assign) BOOL isInsideRegion;//判断是否在圈内

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    _isInsideRegion = NO;
    // 初始化_locationManager并设其代理
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    [self.locationManager requestAlwaysAuthorization];
    

    /**
     iBeacon 本质上来说是一个位置（区域）信息，所以 Apple 把 iBeacon 功能集成在了 Core Location 里面。
     iBeacon 信标在 Core Location 中表现为一个 CLBeacon，它圈定的范围则表现为      CLBeaconRegion，这是一个 CLRegion 的子类。
     CLBeaconRegion 主要用三个属性来标识一个 iBeacon，proximityUUID、major 和 minor。
     proximityUUID 是一个 NSUUID，用来标识公司，每个公司、组织使用的 iBeacon 应该拥有同样的 proximityUUID。
     major 用来识别一组相关联的 beacon，例如在连锁超市的场景中，每个分店的 beacon 应该拥有同样的 major。
     minor 则用来区分某个特定的 beacon。
     这些属性如果不指定（即 nil），匹配的时候就会忽略这个属性。例如只指定 proximityUUID 的 CLBeaconRegion 可以匹配某公司的所有 beacons。
     */
    
    
    // 2.生成监听区域
    // 传入自己使用的ibeacon的UUID(一般说明书上有写)
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"FDA50693-A4E2-4FB1-AFCF-C6EB07647825"];
//    self.myBeaconRegion = [[CLBeaconRegion alloc]initWithProximityUUID:uuid major:1001 minor:19641 identifier:@"hehe"];
    self.myBeaconRegion = [[CLBeaconRegion alloc]initWithProximityUUID:uuid identifier:@"hehe"];
    self.myBeaconRegion.notifyOnExit = YES; //发送离开通知
    self.myBeaconRegion.notifyOnEntry = YES; //发送进入通知
    self.myBeaconRegion.notifyEntryStateOnDisplay = YES;//后台监测ibeacon对象
    [self.myBeaconRegion peripheralDataWithMeasuredPower:@3];
    
    
    /**
     监听方式:可用两种方式检测区域Monitoring或Ranging方式
     Monitoring：可以用来在设备进入/退出某个地理区域时获得通知, 使用这种方法可以在应用程序的后台运行时检测 iBeacon，但是只能同时检测 20 个 region 区域，并且不能够推测设备与 iBeacon 的距离。
     */
    // 此方法只有用户位置发生变化的时候,相应的代理方法才会触发
//    [self.locationManager startMonitoringForRegion:self.myBeaconRegion];
//    [self.locationManager startMonitoringSignificantLocationChanges];
    
    
    // Ranging：可以用来检测某区域内的所有 iBeacons。
    [self.locationManager startRangingBeaconsInRegion:self.myBeaconRegion];
    
    
    return YES;
}

// Monitoring成功对应回调函数
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
    NSLog(@"%@",region);
}

// Ranging成功对应回调函数
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region{
    for (CLBeacon* beacon in beacons) {
//        NSLog(@"远近范围的，一个枚举值:%ld",beacon.proximity);
//        NSLog(@"信号轻度为负值，越接近0信号越强，等于0时无法获取信号强度:%ld",beacon.rssi);
        NSString *UUID = [NSString stringWithFormat:@"%@",beacon.proximityUUID];
        if ([UUID isEqualToString:@"FDA50693-A4E2-4FB1-AFCF-C6EB07647825"]) {
            NSNotification *notification =[NSNotification notificationWithName:@"距离" object:beacon userInfo:nil];
            //通过通知中心发送通知
            [[NSNotificationCenter defaultCenter] postNotification:notification];
        }
    }
}

// 指定区域内确定了状态后触发的代理方法
- (void)locationManager:(CLLocationManager *)manager
      didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
    
    if(state == CLRegionStateInside) {
        _isInsideRegion = YES;
    } else if(state == CLRegionStateOutside) {
        _isInsideRegion = NO;
    } else {
        _isInsideRegion = NO;
    }
}

//发现有iBeacon进入监测范围
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"开始。。。");
    NSNotification *notification =[NSNotification notificationWithName:@"进入" object:nil userInfo:nil];
    //通过通知中心发送通知
    [[NSNotificationCenter defaultCenter] postNotification:notification];
}

//发现有iBeacon离开监测范围
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    NSLog(@"结束。。。");
    NSNotification *notification =[NSNotification notificationWithName:@"离开" object:nil userInfo:nil];
    //通过通知中心发送通知
    [[NSNotificationCenter defaultCenter] postNotification:notification];
}

- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
    NSLog(@"Failed monitoring region: %@", error);
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"Location manager failed: %@", error);
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}


- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}


@end
